package cn.lzy.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author lzy
 * @Date 2023/12/20 8:49
 * @Version
 **/
public class TestDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class);

        // ====================== 1. jdbcTemplate 的基础用法 ======================
        // 1.1 该方法一般用于执行 DDL 操作
//        jdbcTemplate.execute("");

        // 1.2 如果需要批处理的，可以调用该方法
//        jdbcTemplate.batchUpdate("");

        // 1.3 增删改都是调用该方法
//        jdbcTemplate.update("");

        // 1.4 下面都是查询的方法
//        jdbcTemplate.query();
//        jdbcTemplate.queryForObject();
//        jdbcTemplate.queryForList();

        // 1.5 下面演示基本操作
        // 增删改
        add(jdbcTemplate);
        update(jdbcTemplate);
        delete(jdbcTemplate);

        // 查
        query01(jdbcTemplate);
        query02(jdbcTemplate);
        query03(jdbcTemplate);
        query04(jdbcTemplate);
        query05(jdbcTemplate);
        query06(jdbcTemplate);

        // ====================== 2. jdbcTemplate 的基础用法 ======================
        NamedParameterJdbcTemplate namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);
        query07(namedParameterJdbcTemplate);
    }



    // ==================================== 基本查询 =========================================
    private static void add(JdbcTemplate jdbcTemplate) {
        // 返回值就是数据库受影响的行数
        int i = jdbcTemplate.update("insert into user (id, name, address) values (?,?,?);", "7", "诸葛亮", "北京");
        System.out.println("i = " + i);
    }


    private static void update(JdbcTemplate jdbcTemplate) {
        int i = jdbcTemplate.update("update user set address = ? where id=?;", "深圳", 7);
        System.out.println("i = " + i);
    }


    private static void delete(JdbcTemplate jdbcTemplate) {
        int update = jdbcTemplate.update("delete from user where id=?;", 7);
        System.out.println("update = " + update);
    }



    // ==================================== 基本查询 =========================================

    private static void query01(JdbcTemplate jdbcTemplate) {
        jdbcTemplate.query("select * from user where address = ?", new RowCallbackHandler() {
            /**
             * 这里的 processRow 这个方法已经位于一个 while(rs.next()) 中了，所以我们只需要处理 rs 即可，不需要继续往后遍历
             * @param resultSet
             * @throws SQLException
             */
            @Override
            public void processRow(ResultSet resultSet) throws SQLException {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String address = resultSet.getString("address");
                System.out.println(id + "-" + name + "-" + address);
            }
        }, "中山");
    }


    private static void query02(JdbcTemplate jdbcTemplate) {
        System.out.println("******************* 02 ******************");
        List<User> userList = jdbcTemplate.query("select * from user where address = ?", new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet resultSet, int i) throws SQLException {
                User user = new User();
                user.setId(resultSet.getInt("id"));
                user.setName(resultSet.getString("name"));
                user.setAddress(resultSet.getString("address"));
                return user;
            }
        }, "中山");

        for (User user : userList) {
            System.out.println(user);
        }
    }


    private static void query03(JdbcTemplate jdbcTemplate) {
        System.out.println("******************* 03 ******************");
        // BeanPropertyRowMapper 会自动将查询结果映射到对象上，但是有一个前提，就是查询的结果的列名称必须和对象的属性名称保持一致
        List<User> userList = jdbcTemplate.query("select * from user where address = ?", new BeanPropertyRowMapper<>(User.class), "中山");
        for (User user : userList) {
            System.out.println(user);
        }
    }


    private static void query04(JdbcTemplate jdbcTemplate) {
        System.out.println("******************* 04 ******************");
        User user = jdbcTemplate.queryForObject("select * from user where id = ?", new BeanPropertyRowMapper<>(User.class), 1);
        System.out.println(user);
    }


    private static void query05(JdbcTemplate jdbcTemplate) {
        System.out.println("******************* 05 ******************");
        // 注意，第二个参数如果是一些普通对象的话，要求查询结果只能有一列
        String name = jdbcTemplate.queryForObject("select name from user where id = ?", String.class, 1);
        System.out.println(name);
    }


    private static void query06(JdbcTemplate jdbcTemplate) {
        System.out.println("******************* 06 ******************");
        // queryForList 函数，要求查询结果也是只能有一列
        List<String> nameList = jdbcTemplate.queryForList("select name from user", String.class);
        for (String name : nameList) {
            System.out.println("name = " + name);
        }
    }



    private static void query07(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
        System.out.println("******************* 07 ******************");
        Map<String, Object> map = new HashMap<>();
        map.put("address", "中山");
        map.put("id", 5);
        // queryForList 函数，要求查询结果也是只能有一列
        List<User> userList = namedParameterJdbcTemplate.query("select * from user where id < :id and address = :address", map, new BeanPropertyRowMapper<>(User.class));
        for (User user : userList) {
            System.out.println("name = " + user);
        }
    }

}
